
import java.awt.*;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Figueroa
 */
public class PlayBoard extends JPanel   implements MouseListener, MouseMotionListener{
     // width of the chessboard square
   int width;
   // number of black pixels surrounding each square
   int border=3;
   // color of chess squares
   Color lightSquare= Color.white;// new Color(122,122,122);  // light green
   Color darkSquare= new Color(127,127,127);//new Color(234,234,234);     // dark green
   
   boolean whiteTurn=true;;
  public boolean promotion = false;
  private String promoted = "";
  
  public void addListeners(){
  this.addMouseListener(this);
  this.addMouseMotionListener(this);
  }
   // used when dragging pieces from one square to another
   boolean dragging=false;
   boolean temp;
   int tempRow, tempCol;
   int dragRow, dragCol;
   char  dragPiece;
   public String Registry="";
  
   //Unicode Pieces
   //White set
   private String pawnW  = "\u2659";
   private String kingW  = "\u2654";
   private String queenW = "\u2655";
   private String rookW  = "\u2656";
   private String bishopW = "\u2657";
   private String knightW = "\u2658";
 
   //Black set
   private String pawnB  = "\u265F";
   private String kingB  = "\u265A";
   private String queenB = "\u265B";
   private String rookB  = "\u265C";
   private String bishopB = "\u265D";
   private String knightB = "\u265E";
  private ValidacionMovimientos validate = new ValidacionMovimientos();


   
     // remember the location of all pieces on board
   public char piece[] =
        {'R','H','B','Q','K','B','H','R',
         'P','P','P','P','P','P','P','P',
         ' ',' ',' ',' ',' ',' ',' ',' ',
         ' ',' ',' ',' ',' ',' ',' ',' ',
         ' ',' ',' ',' ',' ',' ',' ',' ',
         ' ',' ',' ',' ',' ',' ',' ',' ',
         'p','p','p','p','p','p','p','p',
         'r','h','b','q','k','b','h','r'};
  
  // isWhite -- true if piece is a white chesspiece
  public boolean isWhite(char ch) {
     return (ch>='a' && ch<='z');
  }
  
  public boolean legalMove(int i, int j) {
     // global variables:
     //    subject piece:  dragPiece
     //    from position:  dragCol, dragRow 
      boolean response;
     if (i<0 || i>7 || j<0 || j>7) {
        
        return false;
     }
     int currentPlayer = 2;
     if(isWhite(dragPiece))
         currentPlayer= 1;
     
     response = validate_move(dragPiece,dragRow,dragCol,j,i,currentPlayer);
    
     //Por si hay promocion del peon 
     if(response && promotion){
        if(currentPlayer == 1)
             whiteTurn = false;
         else
             whiteTurn = true;
         //this.update(this.getGraphics());
         return true;
         
     }
      // do not allow move to position occupied by 
     // player making the move
     if (piece[j*8+i]!=' ' && response ) { ///REVISAR ACA
        //'^' is XOR: false if same,  true if different
        response = isWhite(dragPiece)^isWhite(piece[j*8+i]);
     //return true;
     }
     
    return response;
  }
  
  private void labelSquare(Graphics g, int i, int j, String piece) {
    /* Polygon poly=new Polygon();
     for (int ip=0; ip<xpoints.length; ip++) {
        poly.addPoint(pos(i)+xpoints[ip]*width/31,
                      pos(j)+ypoints[ip]*width/31);
      }
      g.fillPolygon(poly);*/
      g.setColor(Color.BLACK);
    //  g.drawPolygon(poly);
      int fontsize = width ;
      g.setFont(new Font("TimesRoman", Font.PLAIN,fontsize));
     // System.out.print("I"+pos(i)+"J"+pos(j));
      g.drawString(piece,pos(i),pos(j)+fontsize-border-3);
  }
  
  // 
  public boolean isDark(int i,int j) {
     // ^ is exclusive or -- true if both operands are the same
     // test: both i and j are even or both i and j are odd
     return ((i&1)^(j&1))!=0;
  }
  
  // determine position of row i or column i
  public int pos(int i) {
     return border+i*(width+border);
     
  }
  
  // position inverse --
  // determine row i or column i from position
  public int posinv(int p) {
     // we solve for i in pos() function 
     return (p-border)/(width+border);
  }
  
  public void drawSquare(Graphics g, int i, int j, boolean red) {
     String[] array = new String[6];
      if (red) {
        g.setColor(new Color(50,205,50));
     } else {
        if (isDark(i,j)) {
           g.setColor(darkSquare);
        } else {
           g.setColor(lightSquare); 
        } 
     }
    
     g.fillRect(pos(i),pos(j),width,width);
     if (isWhite(piece[j*8+i])) {
         
       array[0] = pawnW;
       array[1] = kingW;
       array[2] = queenW;
       array[3] = rookW;
       array[4] = knightW;
       array[5] = bishopW;
     } else {
       array[0] = pawnB;
       array[1] = kingB;
       array[2] = queenB;
       array[3] = rookB;
       array[4] = knightB;
       array[5] = bishopB;
     }
     switch (Character.toUpperCase(piece[j*8+i])) {
     case 'P': labelSquare(g,i,j,array[0]);
               break;
     case 'K': labelSquare(g,i,j,array[1]);
               break;
     case 'Q': labelSquare(g,i,j,array[2]);
               break;
     case 'R': labelSquare(g,i,j,array[3]);
               break;
     case 'H': labelSquare(g,i,j,array[4]);
               break;
     case 'B': labelSquare(g,i,j,array[5]);
               break;
     default:  break;
     }
  }
  
  private void drawBoard(Graphics g) {
     g.setColor(Color.black);
     g.fillRect(0,0,width*8+border*9,width*8+border*9);
     for (int i=0;i<8;i++) {
        for (int j=0;j<8;j++) {
           drawSquare(g,i,j,false);
        }
     
     }
  }
  
    // Paint does all the work -- draw the chessboard
   public void paint(Graphics g) {
     Dimension d=size();
      width=(Math.min(d.width,d.height)-border*9)/8;
      drawBoard(g);      
   }

 

   public void update(Graphics g) {
      paint(g);
   }
   
   
   
  
   
   public boolean setpawnPromotion(String piece_C,int player,int startR, int startC,int desR,int desC ){
   boolean result = false;
   
   if(  "Alfil".equals(piece_C) &&  player == 1){
      piece[startR*8+startC] = ' ';
      piece[desR*8+desC] = 'b';
      promoted = "A";
      result = true;
   }
   else if(  "Alfil".equals(piece_C) &&  player == 2){
      piece[startR*8+startC] = ' ';
      piece[desR*8+desC] = 'B';
       promoted = "A";
      result = true;
   }
   else if(  "Dama".equals(piece_C)&&  player == 1){
      piece[startR*8+startC] = ' ';
      piece[desR*8+desC] = 'q';
       promoted = "D";
      result = true;  
   }
    else if(  "Dama".equals(piece_C) &&  player == 2){
      piece[startR*8+startC] = ' ';
      piece[desR*8+desC] = 'Q';
      promoted = "D";
        result = true;  
   }
    else if(  "Torre".equals(piece_C) &&  player == 1){
      piece[startR*8+startC] = ' ';
      piece[desR*8+desC] = 'r';
      promoted = "T";
        result = true;  
   }
   else if(  "Torre".equals(piece_C) &&  player == 2){
      piece[startR*8+startC] = ' ';
      piece[desR*8+desC] = 'R';
      promoted = "T";
       result = true;  
   }
   else if(  "Caballo".equals(piece_C) &&  player == 1){
      piece[startR*8+startC] = ' ';
      piece[desR*8+desC] = 'h';
      promoted = "C";
       result = true;  
   }
   else if(  "Caballo".equals(piece_C) &&  player == 2){
      piece[startR*8+startC] = ' ';
      piece[desR*8+desC] = 'H';
       promoted = "C";
       result = true;  
   }
   Graphics g = this.getGraphics();
 
   
   
    this.update(g);
   
   return result;
   }
   
   public char get_piece(String p){
   
       if(p.equals(pawnW))
           return 'p';
     else if(p.equals(kingW))
           return 'k';
     else if(p.equals(queenW))
           return 'q';
     else if(p.equals(rookW))
           return 'r';   
     else if(p.equals(knightW))
           return 'h';
     else if(p.equals(bishopW))
           return 'b';
       
      else  if(p.equals(pawnB))
           return 'P';
     else if(p.equals(kingB))
           return 'K';
     else if(p.equals(queenB))
           return 'Q';
     else if(p.equals(rookB))
           return 'R';   
     else if(p.equals(knightB))
           return 'H';
     else if(p.equals(bishopB))
           return 'B';
     else
         return ' ';
      
       
   
   } 
   public String get_piece_name(String p){
   
       if(p.equals(pawnW))
           return "Peón Blanco";
     else if(p.equals(kingW))
           return "Rey Blanco";
     else if(p.equals(queenW))
           return "Reina Blanca";
     else if(p.equals(rookW))
           return "Torre Blanca";   
     else if(p.equals(knightW))
           return "Caballo Blanco";
     else if(p.equals(bishopW))
           return "Alfil Blanco";
       
      else  if(p.equals(pawnB))
           return "Peón Negro";
     else if(p.equals(kingB))
           return "Rey Negro";
     else if(p.equals(queenB))
           return "Reina Negra";
     else if(p.equals(rookB))
           return "Torre Negra";   
     else if(p.equals(knightB))
           return "Caballo Negro";
     else if(p.equals(bishopB))
           return "Alfil Negro";
     else
         return " ";
      
       
   
   }
   
   public String piece_tostring(){
   
   String resul = null;
   
   for(int i=0;i<piece.length;i++){
   resul+=piece[i];
  
   }
   
   return resul;
       
       
   }
   
   public void limpiar(){
   Graphics g=this.getGraphics();
   for(int i=0; i<piece.length;i++){
   piece[i]=' ';
   update(g);
   
   }
   
   }

    private boolean validate_move(char dragPiece,int startR, int startC,int desR,int desC,int currentP) {
     if(dragPiece=='p' || dragPiece == 'P'){
        // System.out.print("SR"+startR+"SC"+startC+"desR"+desC+"desC"+desC);
         
        return validate.validate_pawn(startR, startC, desR, desC, this, currentP);
     }
     else if(dragPiece == 'h' || dragPiece == 'H'){
        return validate.validate_knight(startR, startC, desR, desC);
     }
     else if(dragPiece == 'k' || dragPiece == 'K'){
        return  validate.validate_king(startR, startC, desR, desC);
     }
     else if(dragPiece == 'b' || dragPiece == 'B'){
        return validate.validate_bishop(startR, startC, desR, desC, this);
     }
     else if(dragPiece == 'r' || dragPiece == 'R'){
         return validate.validate_rook(startR, startC, desR, desC, this);
     }
     else if(dragPiece == 'q' || dragPiece == 'Q'){
         return validate.validate_queen(startR, startC, desR, desC, this);
     }
     else
        return false;  
    }
    
    //Translate Chars for algebraic notation
     private char translate_chars(char dragPiece) {
      if(dragPiece == 'h' || dragPiece == 'H'){
        return 'C';
     }
     else if(dragPiece == 'k' || dragPiece == 'K'){
        return 'R';
     }
     else if(dragPiece == 'b' || dragPiece == 'B'){
        return 'A';
     }
     else if(dragPiece == 'r' || dragPiece == 'R'){
         return 'T';
     }
     else if(dragPiece == 'q' || dragPiece == 'Q'){
         return 'D';
     }
     else
        return ' ';
    }
    
    //Gets the algebraic notation of a move
    public String translate_move(int StartRow, int StartColumn, int destRow, int destColumn, char Piece){
         char letras[] = {'a','b','c','d','e','f','g','h'};
         int  numbers[] =  {8,7,6,5,4,3,2,1};
          String move=null;
         if(!promotion)
         move = translate_chars(Piece)+""+letras[StartColumn]+""+numbers[StartRow]+"-"+letras[destColumn]+""+numbers[destRow];
         else
         move = translate_chars(Piece)+""+letras[StartColumn]+""+numbers[StartRow]+"-"+promoted+letras[destColumn]+""+numbers[destRow];   
             
         return move;
    }
  
    
    @Override
    public void mouseClicked(MouseEvent e) {
      
    
    
    }

    @Override
    public void mousePressed(MouseEvent e) {
  
              
        if( e.getSource() == this){
         Graphics g=this.getGraphics();
         int x = e.getX();
         int y = e.getY();
         int i=this.posinv(x);
         int j=this.posinv(y);
         System.out.println("I"+i+"J"+j);
      if (i>=8 || j>=8) {
         return;
      }
      //  do nothing if square is empty
      if (this.piece[j*8+i]==' ') {
         return;
      }
      //  do nothing if square is not one of the
      //  pieces of the color whose turn it is
     if (this.whiteTurn!=this.isWhite(this.piece[j*8+i])) {
         return;
      }
      
      // start dragging a piece      
      this.dragging=true;
      this.temp=false;
      this.dragCol=i;
      this.dragRow=j;
      this.dragPiece=this.piece[j*8+i];
      // highlight the selected square in red
      this.drawSquare(g,i,j,true);
      return;
    }
    
    }

    @Override
    public void mouseReleased(MouseEvent e) {
         if( e.getSource() == this){
     Graphics g=this.getGraphics();
     int x = e.getX();
     int y = e.getY(); 
     int i=this.posinv(x);
      int j=this.posinv(y);
      if (this.dragging) {
         if (this.temp && i>=0 && j<8
                  && !(i==this.dragCol && j==this.dragRow)) {
            // make the temporary move permanent
            this.drawSquare(g,this.tempCol,this.tempRow,false);
            // remove the piece from its old position
            this.piece[this.dragRow*8+this.dragCol]=' ';
             // place piece in its new position
            this.piece[j*8+i]=this.dragPiece;
            this.drawSquare(g,i,j,false);
            if(!this.whiteTurn){
              Registry +=","+this.translate_move(this.dragRow, this.dragCol, j, i, this.dragPiece)+"\n";
            }
            else{
                Registry += ""+this.translate_move(this.dragRow, this.dragCol, j, i, this.dragPiece);
            }
           
            // change the turn
          this.whiteTurn=!this.whiteTurn;
          
         }
         // remove highlighting on old position
         this.drawSquare(g,this.dragCol,this.dragRow,false);
         this.temp=false;
         this.dragging=false;
      }
      return;
    }
    }

    @Override
    public void mouseEntered(MouseEvent e) {
     //
    }

    @Override
    public void mouseExited(MouseEvent e) {
        //Do nothing
    }

    @Override
    public void mouseDragged(MouseEvent e) {
         if( e.getSource() == this){
   //  System.out.print("Mouse dragged");
        Graphics g=this.getGraphics();
       int x = e.getX();
       int y = e.getY();
       int i=this.posinv(x);
       int j=this.posinv(y);
       if (this.dragging) {
         // has nothing changed from last time?
         if (this.temp && i==this.tempCol && j==this.tempRow) {
            return ;
         }
         if (this.temp) {
            // clear the previous temporary move
            this.drawSquare(g,this.tempCol,this.tempRow,false);
            this.temp=false;
         }
         // check for legal move 
         if (this.legalMove(i,j)) {
            // update new position to show the piece
            this.temp=true;
            this.tempCol=i;
            this.tempRow=j;
            this.drawSquare(g,i,j,true);
         }
      }
      return ;
    }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
       // throw new UnsupportedOperationException("Not supported yet.");
    }
  

}